package com.zemb.flxwear.BLE;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.BluetoothLeScanner;
import android.content.Context;
import android.content.pm.PackageManager;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.zemb.flxwear.PERMISSION.PermissionUtils;
import com.zemb.flxwear.Utils.LogUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;

/**
 * BLEUtils
 * 2021-4-1    cby:ZR
 */
public class BLEUtils {

    private final String TAG = "BLEUtils";
    private List<BluetoothDevice> bluetoothDevices;

    private Context context;
    //设备已连接
    private boolean isConnect = false;

    private static BLEUtils instance;
    public static BLEUtils getInstance() {
        if (instance == null) {
            instance = new BLEUtils();
        }
        return instance;
    }
    public BLEUtils() {
        instance = this;
    }


    private String deviceName="无";
    private String serviceId="0000000";


    private Context _context;
    private Activity _activity;
    private BluetoothManager manager;
    private BluetoothAdapter adapter;
    private BluetoothLeScanner scanner;
    private BluetoothGatt bluetoothGatt;
    private boolean isScan = false;
    private UUID uuid;
    private BluetoothGattCharacteristic service;
    private BluetoothDevice mdevice;
    public boolean isInit =false;
    private ScanCallback scanCallback;
    private BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            super.onConnectionStateChange(gatt, status, newState);
            if (newState == BluetoothProfile.STATE_CONNECTED) {
                LogUtils.PrintLog("连接成功");
                isConnect = true;
                gatt.discoverServices();
            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                LogUtils.PrintLog("连接失败");
                isConnect = false;
            }
        }

        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            super.onServicesDiscovered(gatt, status);
            if (status == BluetoothGatt.GATT_SUCCESS) {
                LogUtils.PrintLog("发现服务");
                List<BluetoothGattService> services = gatt.getServices();
                for (BluetoothGattService service : services) {
                    LogUtils.PrintLog("service:"+service.getUuid().toString());
                    List<BluetoothGattCharacteristic> characteristics = service.getCharacteristics();
                    for (BluetoothGattCharacteristic characteristic : characteristics) {
                        LogUtils.PrintLog("characteristic:"+characteristic.getUuid().toString());
                        List<BluetoothGattDescriptor> descriptors = characteristic.getDescriptors();
                        for (BluetoothGattDescriptor descriptor : descriptors) {
                            LogUtils.PrintLog("descriptor:"+descriptor.getUuid().toString());
                        }
                    }
                }
            }
        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicRead(gatt, characteristic, status);
            if (status == BluetoothGatt.GATT_SUCCESS) {
                LogUtils.PrintLog("读取成功");
            }
        }

        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicWrite(gatt, characteristic, status);
            if (status == BluetoothGatt.GATT_SUCCESS) {
                LogUtils.PrintLog("写入成功");
            }
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicChanged(gatt, characteristic);
            LogUtils.PrintLog("数据改变");
        }

        @Override
        public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            super.onDescriptorRead(gatt, descriptor, status);
            if (status == BluetoothGatt.GATT_SUCCESS) {
                LogUtils.PrintLog("读取描述成功");
            }
        }
    };

    private BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(BluetoothDevice bluetoothDevice, int i, byte[] bytes) {
            LogUtils.PrintErr("  address:"+bluetoothDevice.getAddress());
            if(!bluetoothDevices.contains(bluetoothDevice)) {
                bluetoothDevices.add(bluetoothDevice);
                LogUtils.PrintErr("name:"+bluetoothDevice.getName()+"  address:"+bluetoothDevice.getAddress());
            }
            if(scanCallback!=null) scanCallback.onScan(bluetoothDevices);
        }
    };

    public interface ScanCallback{
        void onScan(List<BluetoothDevice> devices);
    }

    public boolean init(Context context){
        //初始化manager
        try {
            bluetoothDevices = new ArrayList<>();
            this._context = context;

            manager = (BluetoothManager) _context.getSystemService(Context.BLUETOOTH_SERVICE);
            assert manager != null;
            //初始化adapter
            adapter = manager.getAdapter();
            adapter.enable();
            isInit = true;
        }catch (Exception e){

            isInit =false;
        }
        return  true;
    }
    public void sendData(byte [] data){
        if(CheckPermission(PermissionUtils.PERMISSIONS_BLUETOOTH)){
            try {
                if(isConnect){
                    service.setValue(data);
                    bluetoothGatt.writeCharacteristic(service);
                }
            }catch (Exception e){

            }
        }

    }


    public boolean IsConnect(){
        if(!isInit) return false;
        return isConnect;

    }
    public boolean disConnect(){
        if(!isInit) return false;

        try {
            bluetoothGatt.disconnect();
        }catch (Exception e){
            e.printStackTrace();
        }
        return  true;
    }

    public void scanDevice(ScanCallback scanCallback){
        //扫描设备 10秒后关闭扫描
        if(!isInit) return;
        this.scanCallback = scanCallback;
        if(!isScan){
            isScan = true;
            adapter.startLeScan(leScanCallback);
            Timer timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    adapter.stopLeScan(leScanCallback);
                    isScan = false;
                }
            }, 100000);
        }


    }
    //通过地址连接设备
    public boolean connectDevice(String address,BluetoothGattCallback gattCallback){
        if(!isInit) return false;
        if(CheckPermission(PermissionUtils.PERMISSIONS_BLUETOOTH)){
            try {
                mdevice = adapter.getRemoteDevice(address);
                bluetoothGatt = mdevice.connectGatt(_context, false, gattCallback);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return true;
    }
   



    public boolean CheckPermission(String [] permissions){
        //检查权限
        for (String permission:permissions) {
            if(ContextCompat.checkSelfPermission(_context,permission)!= PackageManager.PERMISSION_GRANTED){
                return false;
            }
        }
        return true;
    }

}
